#ifndef LOWPASSFILTER_H
#define LOWPASSFILTER_H

#include <QList>

template<typename T>
class LowPassFilter
{
public:
    LowPassFilter(int bufferSize = 1, bool usedSort = false)
    {
        m_bufferSize = bufferSize;
        m_usedSort = usedSort;
    }

    T filter(const T &data)
    {
        if (!m_isEnable)
            return data;

        m_buffer << data;
        while (m_buffer.size() > m_bufferSize)
        {
            m_buffer.takeFirst();
        }

        if (m_usedSort)
        {
            // 排序，去头尾
            QList<T> buffer = m_buffer;
            std::sort(buffer.begin(), buffer.end());
            int takeLen = buffer.size() / 4;
            for (int i = 0; i < takeLen; i++)
            {
                buffer.takeFirst();
                buffer.takeLast();
            }

            // 加权平均
            T sum = 0; // 注意这里有可能会溢出
            T factor = 0;
            int len = buffer.size();
            T weight;
            for (int i = 0; i < len; i++)
            {
                if (len % 2)
                {
                    if (i <= len / 2)
                        weight = i + 1;
                    else
                        weight = len - i;
                }
                else
                {
                    if (i < len / 2)
                        weight = i + 1;
                    else
                        weight = len - i;
                }
                sum +=  weight * buffer.at(i);
                factor += weight;
            }
            return (sum / factor);
        }
        else
        {
            // 加权平均
            T sum = 0; // 注意这里有可能会溢出
            T factor = 0;
            for (int i = 0; i < m_buffer.size(); i++)
            {
                sum += (i + 1) * m_buffer.at(i);
                factor += (i + 1);
            }
            return (sum / factor);
        }
    }

    void setBufferSize(int size)
    {
        m_bufferSize = size;
    }

    void setUsedSort(bool usedSort)
    {
        m_usedSort = usedSort;
    }

    void clear()
    {
        m_buffer.clear();
    }

    void setEnable(bool en)
    {
        m_isEnable = en;
    }

private:
    QList<T>            m_buffer;
    int                 m_bufferSize = 1;

    bool                m_usedSort = false;

    bool                m_isEnable = true;
};

#endif // LOWPASSFILTER_H
